﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    public static partial class ObjectExtension
    {
        /// <summary>
        /// 从 lambda 表达式中获取模型名称
        /// </summary>
        /// <param name="expression"></param>
        /// <returns>模型名称</returns>
        public static string GetExpressionText(this LambdaExpression expression)
        {
            return expression.FindProperty().Name;
        }

        /// <summary>
        /// 从 lambda 表达式中获取memberInfo
        /// </summary>
        /// <param name="lambdaExpression"></param>
        /// <returns></returns>
        public static MemberInfo FindProperty(this LambdaExpression lambdaExpression)
        {
            Expression expressionToCheck = lambdaExpression;
            var done = false;
            while (!done)
            {
                switch (expressionToCheck.NodeType)
                {
                    case ExpressionType.Convert:
                        expressionToCheck = ((UnaryExpression)expressionToCheck).Operand;
                        break;
                    case ExpressionType.Lambda:
                        expressionToCheck = ((LambdaExpression)expressionToCheck).Body;
                        break;
                    case ExpressionType.MemberAccess:
                        var memberExpression = ((MemberExpression)expressionToCheck);

                        if (memberExpression.Expression.NodeType != ExpressionType.Parameter &&
                            memberExpression.Expression.NodeType != ExpressionType.Convert)
                        {
                            throw new ArgumentException(string.Format("Expression '{0}' 不支持", lambdaExpression), "lambdaExpression");
                        }
                        var member = memberExpression.Member;

                        return member;
                    default:
                        done = true;
                        break;
                }
            }

            throw new ArgumentException("不支持此 lambda 表达式");
        }
    }
}
